/**
 * 游戏核心类，负责游戏逻辑和渲染
 */
class Game {
    /**
     * 初始化游戏
     * 设置画布、玩家、球体和游戏状态
     */
    constructor() {
        // 获取画布和上下文
        this.canvas = document.getElementById('gameCanvas');
        this.ctx = this.canvas.getContext('2d', { willReadFrequently: true });
        this.canvas.width = 600;
        this.canvas.height = 400;
        
        // 初始化玩家
        this.player = {
            x: this.canvas.width / 2,
            y: this.canvas.height / 2,
            radius: 10,
            speed: 5
        };
        
        // 初始化球体数组和游戏状态
        this.poisonBalls = [];    // 毒药球（蓝色）
        this.medicineBalls = [];  // 解药球（绿色）
        this.score = 0;           // 游戏分数
        this.isTraining = false;  // 训练状态
        this.gameSpeed = 1;       // 游戏速度
        
        // 创建初始球体
        this.initializeBalls();
    }

    /**
     * 初始化毒药球和解药球
     * 每种球各创建10个，设置随机位置和速度
     */
    initializeBalls() {
        // 初始化毒药球，添加速度属性
        for (let i = 0; i < 10; i++) {
            this.poisonBalls.push({
                x: Math.random() * (this.canvas.width - 20) + 10,
                y: Math.random() * (this.canvas.height - 20) + 10,
                radius: 8,
                speedX: (Math.random() - 0.5) * 4,  // -2 到 2 之间的随机速度
                speedY: (Math.random() - 0.5) * 4
            });
        }
        
        // 初始化解药球，添加速度属性
        for (let i = 0; i < 10; i++) {
            this.medicineBalls.push({
                x: Math.random() * (this.canvas.width - 20) + 10,
                y: Math.random() * (this.canvas.height - 20) + 10,
                radius: 8,
                speedX: (Math.random() - 0.5) * 4,
                speedY: (Math.random() - 0.5) * 4
            });
        }
    }

    /**
     * 更新所有球的位置
     * 处理球体的移动和边界碰撞
     */
    updateBalls() {
        // 更新毒药球位置
        this.poisonBalls.forEach(ball => {
            // 根据速度和游戏速度更新位置
            ball.x += ball.speedX * this.gameSpeed;
            ball.y += ball.speedY * this.gameSpeed;

            // 碰到墙壁反弹
            if (ball.x - ball.radius <= 0 || ball.x + ball.radius >= this.canvas.width) {
                ball.speedX *= -1;  // 水平方向速度反转
                ball.x = Math.max(ball.radius, Math.min(this.canvas.width - ball.radius, ball.x));
            }
            if (ball.y - ball.radius <= 0 || ball.y + ball.radius >= this.canvas.height) {
                ball.speedY *= -1;  // 垂直方向速度反转
                ball.y = Math.max(ball.radius, Math.min(this.canvas.height - ball.radius, ball.y));
            }
        });

        // 更新解药球位置（逻辑同上）
        this.medicineBalls.forEach(ball => {
            ball.x += ball.speedX * this.gameSpeed;
            ball.y += ball.speedY * this.gameSpeed;

            if (ball.x - ball.radius <= 0 || ball.x + ball.radius >= this.canvas.width) {
                ball.speedX *= -1;
                ball.x = Math.max(ball.radius, Math.min(this.canvas.width - ball.radius, ball.x));
            }
            if (ball.y - ball.radius <= 0 || ball.y + ball.radius >= this.canvas.height) {
                ball.speedY *= -1;
                ball.y = Math.max(ball.radius, Math.min(this.canvas.height - ball.radius, ball.y));
            }
        });
    }

    /**
     * 绘制游戏画面
     * 包括玩家、球体和分数
     */
    draw() {
        // 清空画布
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        
        // 更新所有球的位置
        this.updateBalls();
        
        // 绘制玩家（红色圆形）
        this.ctx.fillStyle = 'red';
        this.ctx.beginPath();
        this.ctx.arc(this.player.x, this.player.y, this.player.radius, 0, Math.PI * 2);
        this.ctx.fill();
        
        // 绘制毒药球（蓝色）
        this.ctx.fillStyle = 'blue';
        this.poisonBalls.forEach(ball => {
            this.ctx.beginPath();
            this.ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
            this.ctx.fill();
        });
        
        // 绘制解药球（绿色）
        this.ctx.fillStyle = 'green';
        this.medicineBalls.forEach(ball => {
            this.ctx.beginPath();
            this.ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
            this.ctx.fill();
        });
        
        // 绘制分数
        this.ctx.fillStyle = 'black';
        this.ctx.font = '20px Arial';
        this.ctx.fillText(`分数: ${this.score}`, 10, 30);
    }

    /**
     * 检查碰撞
     * 处理玩家与球体的碰撞
     */
    checkCollisions() {
        // 检查与毒药球的碰撞
        this.poisonBalls.forEach(ball => {
            const distance = Math.sqrt(
                Math.pow(this.player.x - ball.x, 2) + 
                Math.pow(this.player.y - ball.y, 2)
            );
            if (distance < this.player.radius + ball.radius) {
                this.score -= 10;  // 碰到毒药球扣分
                this.resetBall(ball);
            }
        });
        
        // 检查与解药球的碰撞
        this.medicineBalls.forEach(ball => {
            const distance = Math.sqrt(
                Math.pow(this.player.x - ball.x, 2) + 
                Math.pow(this.player.y - ball.y, 2)
            );
            if (distance < this.player.radius + ball.radius) {
                this.score += 10;  // 碰到解药球加分
                this.resetBall(ball);
            }
        });
    }

    /**
     * 重置球的位置和速度
     * @param {Object} ball - 要重置的球体对象
     */
    resetBall(ball) {
        ball.x = Math.random() * (this.canvas.width - 20) + 10;
        ball.y = Math.random() * (this.canvas.height - 20) + 10;
        // 重置时也重新随机速度
        ball.speedX = (Math.random() - 0.5) * 4;
        ball.speedY = (Math.random() - 0.5) * 4;
    }

    /**
     * 获取游戏状态
     * @returns {Array} 包含所有游戏对象位置的归一化数组
     */
    getState() {
        // 返回一个包含所有游戏对象位置的数组
        const state = [
            this.player.x / this.canvas.width,  // 归一化玩家位置
            this.player.y / this.canvas.height
        ];

        // 添加毒药球位置
        this.poisonBalls.forEach(ball => {
            state.push(ball.x / this.canvas.width);
            state.push(ball.y / this.canvas.height);
        });

        // 添加解药球位置
        this.medicineBalls.forEach(ball => {
            state.push(ball.x / this.canvas.width);
            state.push(ball.y / this.canvas.height);
        });

        return state;  // 返回一个长度为42的数组（1个玩家2个坐标 + 20个球各2个坐标）
    }

    /**
     * 移动玩家
     * @param {number} action - 动作代码（0:上, 1:下, 2:左, 3:右）
     */
    move(action) {
        switch(action) {
            case 0: // 上
                this.player.y = Math.max(this.player.radius, this.player.y - this.player.speed);
                break;
            case 1: // 下
                this.player.y = Math.min(this.canvas.height - this.player.radius, this.player.y + this.player.speed);
                break;
            case 2: // 左
                this.player.x = Math.max(this.player.radius, this.player.x - this.player.speed);
                break;
            case 3: // 右
                this.player.x = Math.min(this.canvas.width - this.player.radius, this.player.x + this.player.speed);
                break;
        }
    }
} 